"""Ascertain the settings file from command-line options and then parse the
settings"""
import os
from optparse import OptionParser
from ConfigParser import RawConfigParser

import pygame
def mkdir(newdir):
    """works the way a good mkdir should :)
        - already exists, silently complete
        - regular file in the way, raise an exception
        - parent directory(ies) does not exist, make them as well
    """
    if os.path.isdir(newdir):
        pass
    elif os.path.isfile(newdir):
        raise OSError("a file with the same name as the desired " \
                      "dir, '%s', already exists." % newdir)
    else:
        head, tail = os.path.split(newdir)
        if head and not os.path.isdir(head):
            mkdir(head)
        #print "_mkdir %s" % repr(newdir)
        if tail:
            os.mkdir(newdir)

class Container(dict):
	"""A dict who's contents can be gained by attribute access. Unpythonic
	perhaps, but optparse does it and it makes my code prettier!"""
	
	def __getattr__(self, item):
		return self[item]

class Settings(Container):
	"""A wrapper for RawConfigParser that finds the options used by Defence and
	constructs/processes them"""	
	
	def __init__(self, path="./"):
		"""If file is given then path is the directory that filepaths are
		relative to. Otherwise path is loaded as the settings file."""
		super(Settings, self).__init__()
		
		_file = open(path)
		path = os.path.dirname(path)
		
		self.path = path
		
		def normalise(path):
			"""Turn a path into an absolute, user-expanded, normalised path"""
			#path = os.path.join(self.path, path)
			path = os.path.expanduser(path)
			path = os.path.normpath(path)
			path = os.path.abspath(path)
			
			return path 
		
		self._parser = RawConfigParser()
		self._parser.readfp(_file)
		
		user_settings = normalise(os.path.join("~", ".defence", "settings.ini"))
		self._parser.read(user_settings)
		
		def get_pygame_key(name):
			"""Find the pygame key that corresponds to the given name"""
			try:
				key = getattr(pygame, "K_%s" % name.lower())
			except AttributeError:
				key = getattr(pygame, "K_%s" % name.upper())
				
			return key
		
		def font(name, size):
			"""Return a pygame Font of the font in the fonts directory named
			name"""
			fontpath = os.path.join(self.paths.fonts, "%s.ttf" % name)
			return pygame.font.Font(fontpath, size)
		
		self["paths"] = Container(
			(name, normalise(path)) for name, path in self._parser.items("paths"))
		
		for path in self.paths.itervalues():
			mkdir(path)
		
		self["controls"] = Container(
			(name, get_pygame_key(key)) for name, key in self._parser.items("controls"))
		
		self["menu"] = Container(
			item for item in self._parser.items("menu"))
		
		self["fonts"] = Container(
			(name, font(name, size)) for name, size in (("title", 64), ("text", 8)))
		
		self["game"] = Container(
			(name, int(value)) for name, value in self._parser.items("game"))

_DEFAULT_SETTINGS = os.path.join(os.path.dirname(__file__), "..", 
	"settings.ini")

_PARSER = OptionParser()
_PARSER.add_option("--settings", help="The file to load settings from.", 
	action="store", dest="settings_file", default=_DEFAULT_SETTINGS)
_PARSER.add_option("--profile", help="Profile Defence.", 
	action="store_true", dest="profile", default=False)
_PARSER.add_option("--nopsyco", help="Run Defence without psyco module.", 
	action="store_false", dest="psyco", default=True)

_OPTIONS, _ARGS = _PARSER.parse_args()
settings = Settings(path=_OPTIONS.settings_file)
settings.profile = _OPTIONS.profile
settings.psyco = _OPTIONS.psyco
